package com.epoint.mybatispluslearning;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.epoint.mybatispluslearning.domain.Inspection;
import com.epoint.mybatispluslearning.domain.SpcInspectionRecord;
import com.epoint.mybatispluslearning.mapper.InspectionMapper;
import com.epoint.mybatispluslearning.mapper.SpcInspectionRecordMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.UUID;

@SpringBootTest
class MybatisplusLearningApplicationTests_plus {

	@Autowired
	private InspectionMapper inspectionMapper;
	@Autowired
	private SpcInspectionRecordMapper spcInspectionRecordMapper;

	@Test
	void contextLoads() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD123");
		inspection.setProjectguid("001");
		inspection.setName("测试嗷嗷嗷");
		inspection.setCreatedate(new Date());
		inspectionMapper.insert(inspection);
	}

	@Test
	void contextLoads2() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD123");
		inspection.setProjectguid("嘻嘻嘻嘻嘻");
		inspection.setName("嘻嘻嘻嘻嘻");
		inspection.setCreatedate(new Date());
		inspectionMapper.updateById(inspection);
	}

	/**
	 * activerecord
	 */
	@Test
	void contextLoads3() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD1234");
		inspection.setProjectguid("嘻嘻嘻嘻嘻");
		inspection.setName("嘻嘻嘻嘻嘻");
		inspection.setCreatedate(new Date());

		inspection.insert();
	}

	/**
	 * activerecord
	 */
	@Test
	void contextLoads4() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD1234");
		inspection.setProjectguid("嘻嘻嘻嘻嘻123");
		inspection.setCreatedate(new Date());

		inspection.updateById();
	}

	/**
	 * tablename
	 */
	@Test
	void contextLoads5() {
		SpcInspectionRecord spcInspectionRecord = new SpcInspectionRecord();
		spcInspectionRecord.setRowguid(UUID.randomUUID().toString());
		spcInspectionRecord.setProjectguid("1");
		spcInspectionRecord.setInspectionguid("1");
		spcInspectionRecord.setInspectionuser("纪宽豪");
		spcInspectionRecord.setCreatedate(new Date());

		spcInspectionRecordMapper.insert(spcInspectionRecord);
	}

	/**
	 * 自定义扩展的方法
	 */
	@Test
	void contextLoads6() {
		List<Inspection> list = inspectionMapper.getAllByMapProjectAndName("001", "测试嗷嗷嗷");
		System.out.println(list);
	}

	/**
	 * 自动填充策略
	 */
	@Test
	void contextLoads7() {
		Inspection inspection = new Inspection();
		inspection.setRowguid(UUID.randomUUID().toString());
		inspection.setProjectguid("嘻嘻嘻嘻嘻123");
		inspection.setName("你好吗？？？");
		// 我不显示的插入时间，而是使用自动填充策略去做，观察插入后，时间是否存进去
//		inspection.setCreatedate(new Date());

		inspectionMapper.insert(inspection);
	}

	/**
	 * 乐观锁
	 */
	@Test
	void contextLoads8() {
		Inspection inspection = new Inspection();
		inspection.setRowguid(UUID.randomUUID().toString());
		inspection.setProjectguid("嘻嘻嘻嘻嘻123");
		inspection.setName("你好吗？？？");
		// 自动维护了 Version
		/**
		 * 日志
		 * ==>  Preparing: INSERT INTO inspection ( rowguid, projectguid, name, version, createdate ) VALUES ( ?, ?, ?, ?, ? )
		 * ==> Parameters: c42c416f-bc75-4de2-93e6-0df29d05b361(String), 嘻嘻嘻嘻嘻123(String), 你好吗？？？(String), 0(Integer), 2021-08-30 00:21:08.596(Timestamp)
		 * <==    Updates: 1
		 */
		inspectionMapper.insert(inspection);
	}

	/**
	 * 乐观锁2
	 */
	@Test
	void contextLoads9() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD1234");
		inspection.setProjectguid("嘻嘻嘻嘻嘻123");
		inspection.setName("你好吗？？？");
		// 自动维护了 Version
		/**
		 * 日志
		 * ==>  Preparing: UPDATE inspection SET projectguid=?, name=?, version=? WHERE rowguid=? AND version=?
		 * ==> Parameters: 嘻嘻嘻嘻嘻123(String), 你好吗？？？(String), 1(Integer), DDD1234(String), 0(Integer)
		 * <==    Updates: 0
		 */
		inspectionMapper.updateById(inspection);
	}

	/**
	 * 乐观锁3
	 */
	@Test
	void contextLoads10() {
		Inspection in = inspectionMapper.selectById("DDD1234");
		in.setProjectguid("纪宽豪1111111");

		// 自动维护了 Version
		Inspection in2 = inspectionMapper.selectById("DDD1234");
		in2.setProjectguid("纪宽豪2222222");

		// 其实inspection 和 inspection2 是一个记录，但是我抢先执行inspection2，然后观察日志
		inspectionMapper.updateById(in2);
		inspectionMapper.updateById(in);

		/**
		 * 日志
		 * ==>  Preparing: UPDATE inspection SET projectguid=?, name=?, version=?, createdate=? WHERE rowguid=? AND version=?
		 * ==> Parameters: 纪宽豪2222222(String), 你好吗？？？(String), 5(Integer), 2021-08-29 20:16:27.0(Timestamp), DDD1234(String), 4(Integer)
		 * <==    Updates: 1
		 *
		 * ==>  Preparing: UPDATE inspection SET projectguid=?, name=?, version=?, createdate=? WHERE rowguid=? AND version=?
		 * ==> Parameters: 纪宽豪1111111(String), 你好吗？？？(String), 5(Integer), 2021-08-29 20:16:27.0(Timestamp), DDD1234(String), 4(Integer)
		 * <==    Updates: 0
		 *
		 * 结果：
		 * 数据库里 in2插入成功，in插入失败
		 * 因为乐观锁对应的version的原因，整个过程：
		 * 		1.Inspection in = inspectionMapper.selectById("DDD1234");获取的version 4
		 * 		2.Inspection in2 = inspectionMapper.selectById("DDD1234");获取的version 也是4
		 * 		3.inspectionMapper.updateById(in2);之后 把数据库的version从4-》5
		 * 		4.inspectionMapper.updateById(in);执行的时候，发现手里的version 4 已经“过期”了，最新的是version5了，所以执行失败
		 *
		 * 	其实我们自己也能想到这种方案，刚入职的时候觉得用updatetime即可了，也是查询出来后，再去插入的时候 判断是否过期，但是mp最牛逼的时候，他可以帮我们
		 * 	做到“毫无感知”的去获取、去判断、去维护version版本号。
		 */
	}

	@Test
	void contextLoads11() {
		Map<String, Object> parmas = new HashMap<>();
		parmas.put("name", "你好吗？？？");

		Page<Inspection> page = new Page<>(2, 5);

		/**
		 * 日志
		 * ==>  Preparing: SELECT rowguid,projectguid,name,version,createdate FROM inspection LIMIT ? OFFSET ?
		 * ==> Parameters: 5(Long), 5(Long)
		 */
		inspectionMapper.selectPage(page, null);
	}

	/**
	 * 逻辑删除-isdel
	 */
	@Test
	void contextLoads12() {
		Inspection inspection = new Inspection();
		inspection.setRowguid("DDD1234555");
		inspection.setProjectguid("嘻嘻嘻嘻嘻123");
		inspection.setName("你好吗？？？");
		// 自动维护了 isdel
		/**
		 * 日志
		 * ==>  Preparing: INSERT INTO inspection ( rowguid, projectguid, name, isdel, version, createdate ) VALUES ( ?, ?, ?, ?, ?, ? )
		 * ==> Parameters: DDD1234555(String), 嘻嘻嘻嘻嘻123(String), 你好吗？？？(String), 0(Integer), 0(Integer), 2021-08-30 07:49:08.949(Timestamp)
		 * <==    Updates: 1
		 */
//		inspectionMapper.insert(inspection);

		/**
		 * 日志
		 * ==>  Preparing: UPDATE inspection SET isdel=1 WHERE rowguid=? AND isdel=0
		 * ==> Parameters: DDD1234555(String)
		 * <==    Updates: 1
		 *
		 * 可以看到原来delete语句变成了 update
		 */
//		inspectionMapper.deleteById("DDD1234555");

		/**
		 * 验证逻辑删除：我试试select方法，是不是自动把isdel=0条件带入
		 * ==>  Preparing: SELECT rowguid,projectguid,name,isdel,version,createdate FROM inspection WHERE rowguid=? AND isdel=0
		 * ==> Parameters: DDD1234555(String)
		 * <==      Total: 0
		 */
		Inspection ddd1234555 = inspectionMapper.selectById("DDD1234555");
	}

	/**
	 * 条件构造器
	 * 虽然已经提供给了selectByMap这种，但是都是精确查询，没有做模糊、 > < = != 这些
	 * AbstractWrapper提供了非常强大的单表查询，可以说使用mybatisplus能操作单表的所有动作
	 */
	@Test
	void contextLoads13() {
		QueryWrapper<Inspection> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("name", "你好吗？？？")
				.like("projectguid", "123")
				.ge("createdate", new Date())
				.isNotNull("version")
				.inSql("rowguid", "select DISTINCT inspectionguid from inspection_record");
		/**
		 * ==>  Preparing: SELECT rowguid,projectguid,name,isdel,version,createdate FROM inspection WHERE isdel=0 AND
		 * 		(name = ? AND projectguid LIKE ? AND createdate >= ? AND version IS NOT NULL AND rowguid IN (select DISTINCT inspectionguid from inspection_record))
		 * ==> Parameters: 你好吗？？？(String), %123%(String), 2021-08-30 12:58:59.093(Timestamp)
		 */
		inspectionMapper.selectList(queryWrapper);
	}
}
